package com.abc.encryption;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;

public class AES {


   public static String doEncrypt(String content, String password) {
      try {
         KeyGenerator kgen = KeyGenerator.getInstance("AES");
         kgen.init(128, new SecureRandom(password.getBytes()));
         SecretKey secretKey = kgen.generateKey();
         byte[] enCodeFormat = secretKey.getEncoded();
         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
         Cipher cipher = Cipher.getInstance("AES");// 创建密码器
         byte[] byteContent = content.getBytes("UTF-8");
         cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
         byte[] result = cipher.doFinal(byteContent);
         String encryptResultStr = parseByte2HexStr(result);
         return encryptResultStr;
      }
      catch (Exception e) {
         e.printStackTrace();
      }
      return null;
   }

   public static String doDecrypt(String content, String password) {
      try {
         KeyGenerator kgen = KeyGenerator.getInstance("AES");
         kgen.init(128, new SecureRandom(password.getBytes()));
         SecretKey secretKey = kgen.generateKey();
         byte[] enCodeFormat = secretKey.getEncoded();
         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
         Cipher cipher = Cipher.getInstance("AES");
         cipher.init(Cipher.DECRYPT_MODE, key);
         byte[] decryptFrom = parseHexStr2Byte(content);
         byte[] result = cipher.doFinal(decryptFrom);
         return new String(result);
      }
      catch (Exception e) {
         e.printStackTrace();
      }
      return null;
   }

   public static String parseByte2HexStr(byte buf[]) {
      StringBuffer sb = new StringBuffer();
      for (int i = 0; i < buf.length; i++) {
         String hex = Integer.toHexString(buf[i] & 0xFF);
         if (hex.length() == 1) {
            hex = '0' + hex;
         }
         sb.append(hex.toUpperCase());
      }
      return sb.toString();
   }

   public static byte[] parseHexStr2Byte(String hexStr) {
      if (hexStr.length() < 1)
         return null;
      byte[] result = new byte[hexStr.length() / 2];
      for (int i = 0; i < hexStr.length() / 2; i++) {
         int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
         int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
         result[i] = (byte) (high * 16 + low);
      }
      return result;
   }

   public static byte[] md5Encrypt(String str) {
      try {
         MessageDigest digest = MessageDigest.getInstance("Md5");
         return digest.digest(str.getBytes());
      }
      catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
         return null;
      }
   }

   public static void main(String[] args) {
      //1、
      String dataStr = "{}";
      String xAppId = "c2e3e4b91a1e19d506c4915156c48d12";
      String secretkey = "9b0e4794194b6c8ed0d1a903c8895477";

      // 加密
      System.out.println("加密前：" + dataStr);
      String encryptData = EncryptUtil.getInstance().AESencode(dataStr, secretkey);
//    String encryptData = doEncrypt(dataStr, secretkey);
      System.out.println("加密后：" + encryptData);

      //签名
      //当前时间 ---是否超过10分钟
      Long timeStamp = System.currentTimeMillis();
      String nonce = UUID.randomUUID().toString();
      //签名字符串格式：secretkey(加密盐) + encryptData(加密后业务参数) + nonce(随机字符串)
      // + xAppId(合作标识) + timeStamp(时间戳) + secretkey(加密盐)
      String signStr = secretkey + encryptData + nonce + xAppId + timeStamp + secretkey;
      String sign = parseByte2HexStr(md5Encrypt(signStr)).toUpperCase();
      System.out.println("timeStamp：" + timeStamp);
      System.out.println("nonce：" + nonce);
      System.out.println("签名后sign：" + sign);

      //对比签名

      // 解密
      String decryptResult = EncryptUtil.getInstance().AESdecode(encryptData, secretkey);
//      String decryptResult = doDecrypt(encryptData, secretkey);
      System.out.println("解密后：" + decryptResult);

   }


}
